home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 008 / src / hack.mon.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  21KB  |  772 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.mon.c version 1.0.1 - some unimportant changes */
  3.  
  4. #include "hack.h"
  5. #include "hack.mfndpos.h"
  6. #define   SIZE(x)   (int)(sizeof(x) / sizeof(x[0]))
  7. #define   NULL   (char *) 0
  8. extern struct monst *makemon();
  9.  
  10. int warnlevel;      /* used by movemon and dochugw */
  11. long lastwarntime;
  12. int lastwarnlev;
  13. char *warnings[] = {
  14.    "white", "pink", "red", "ruby", "purple", "black"
  15. };
  16.  
  17. movemon()
  18. {
  19.    register struct monst *mtmp;
  20.    register int fr;
  21.  
  22.    warnlevel = 0;
  23.  
  24.    while(1) {
  25.       /* find a monster that we haven't treated yet */
  26.       /* note that mtmp or mtmp->nmon might get killed
  27.          while mtmp moves, so we cannot just walk down the
  28.          chain (even new monsters might get created!) */
  29.       for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  30.          if(mtmp->mlstmv < moves) goto next_mon;
  31.       /* treated all monsters */
  32.       break;
  33.  
  34.    next_mon:
  35.       mtmp->mlstmv = moves;
  36.       if(mtmp->mblinded && !--mtmp->mblinded)
  37.          mtmp->mcansee = 1;
  38.       if(mtmp->mimic) continue;
  39.       if(mtmp->mspeed != MSLOW || !(moves%2)){
  40.          /* continue if the monster died fighting */
  41.          fr = -1;
  42.          if(Conflict && cansee(mtmp->mx,mtmp->my)
  43.             && (fr = fightm(mtmp)) == 2)
  44.             continue;
  45.          if(fr<0 && dochugw(mtmp))
  46.             continue;
  47.       }
  48.       if(mtmp->mspeed == MFAST && dochugw(mtmp))
  49.          continue;
  50.    }
  51.  
  52.    warnlevel -= u.ulevel;
  53.    if(warnlevel >= SIZE(warnings))
  54.       warnlevel = SIZE(warnings)-1;
  55.    if(warnlevel >= 0)
  56.    if(warnlevel > lastwarnlev || moves > lastwarntime + 5){
  57.        register char *rr;
  58.        switch(Warning & (LEFT_RING | RIGHT_RING)){
  59.        case LEFT_RING:
  60.       rr = "Your left ring glows";
  61.       break;
  62.        case RIGHT_RING:
  63.       rr = "Your right ring glows";
  64.       break;
  65.        case LEFT_RING | RIGHT_RING:
  66.       rr = "Both your rings glow";
  67.       break;
  68.        default:
  69.       rr = "Your fingertips glow";
  70.       break;
  71.        }
  72.        pline("%s %s!", rr, warnings[warnlevel]);
  73.        lastwarntime = moves;
  74.        lastwarnlev = warnlevel;
  75.    }
  76.  
  77.    dmonsfree();   /* remove all dead monsters */
  78. }
  79.  
  80. justswld(mtmp,name)
  81. register struct monst *mtmp;
  82. char *name;
  83. {
  84.  
  85.    mtmp->mx = u.ux;
  86.    mtmp->my = u.uy;
  87.    u.ustuck = mtmp;
  88.    pmon(mtmp);
  89.    kludge("%s swallows you!",name);
  90.    more();
  91.    seeoff(1);
  92.     u.uswldtim = 0;
  93.     u.uswallow = 1;
  94.     swallowed();
  95. }
  96.  
  97. youswld(mtmp,dam,die,name)
  98. register struct monst *mtmp;
  99. register int dam,die;
  100. char *name;
  101. {
  102.    if(mtmp != u.ustuck) return;
  103.    kludge("%s digests you!",name);
  104.    u.uhp -= dam;
  105.    if(u.uswldtim++ == die){
  106.       pline("It totally digests you!");
  107.       u.uhp = -1;
  108.    }
  109.    if(u.uhp < 1) done_in_by(mtmp);
  110. }
  111.  
  112. dochugw(mtmp) register struct monst *mtmp; {
  113. register int x = mtmp->mx;
  114. register int y = mtmp->my;
  115. register int d = dochug(mtmp);
  116. register int dd;
  117.    if(!d)      /* monster still alive */
  118.    if(Warning)
  119.    if(!mtmp->mpeaceful)
  120.    if((dd = dist(mtmp->mx,mtmp->my)) < dist(x,y))
  121.    if(dd < 100)
  122.    if(!cansee(mtmp->mx, mtmp->my) || (mtmp->minvis && !See_invisible))
  123.    if(mtmp->data->mlevel > warnlevel)
  124.       warnlevel = mtmp->data->mlevel;
  125.    return(d);
  126. }
  127.  
  128. /* returns 1 if monster died moving, 0 otherwise */
  129. dochug(mtmp)
  130. register struct monst *mtmp;
  131. {
  132.    register struct permonst *mdat;
  133.    register int tmp;
  134.  
  135.    if(mtmp->cham && !rn2(6))
  136.       (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]);
  137.    mdat = mtmp->data;
  138.    if(mdat->mlevel < 0)
  139.       panic("bad monster %c (%d)",mdat->mlet,mdat->mlevel);
  140.    if((!(moves%20) || index("ViT",mdat->mlet)) &&
  141.        mtmp->mhp<mtmp->orig_hp)
  142.       mtmp->mhp++; /* regenerate monsters. */
  143.    if(mtmp->mfroz) return(0); /* frozen monsters don't do anything. */
  144.    if(mtmp->msleep) {/* wake up a monster, or get out of here. */
  145.       if(cansee(mtmp->mx,mtmp->my) && !Stealth &&
  146.          (!index("NL",mdat->mlet) || !rn2(50)) &&
  147.          (Aggravate_monster || (!rn2(7) && !mtmp->mimic)))
  148.          mtmp->msleep = 0;
  149.       else return(0);
  150.    }
  151.  
  152.    /* not frozen or sleeping: wipe out texts written in the dust */
  153.    wipe_engr_at(mtmp->mx, mtmp->my, 1);
  154.  
  155.    /* confused monsters get unconfused with small probability */
  156.    if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
  157.  
  158.    /* some monsters teleport */
  159.    if(mtmp->mflee && index("tNL", mdat->mlet) && !rn2(40)){
  160.       rloc(mtmp);
  161.       return(0);
  162.    }
  163.    if(mdat->mmove < rnd(6)) return(0);
  164.    if((mtmp->mflee ||
  165.       mtmp->mconf ||
  166.       (index("BIuy", mdat->mlet) && !rn2(4)) ||
  167.       (mdat->mlet == 'L' && !u.ugold && (mtmp->mgold || rn2(2))) ||
  168.       dist(mtmp->mx,mtmp->my) > 2 ||
  169.       (!mtmp->mcansee && !rn2(4)) ||
  170.       mtmp->mpeaceful
  171.       ) && (tmp = m_move(mtmp,0)) && mdat->mmove <= 12)
  172.       return(tmp == 2);
  173.    if(tmp == 2) return(1);   /* monster died moving */
  174.  
  175.    if(!index("Ea", mdat->mlet) && dist(mtmp->mx, mtmp->my) < 3 &&
  176.     !mtmp->mpeaceful && u.uhp > 0 &&
  177.     !sengr_at("Elbereth", u.ux, u.uy) &&
  178.     !sobj_at(SCR_SCARE_MONSTER, u.ux, u.uy)) {
  179.       if(mhitu(mtmp))
  180.          return(1);   /* monster died (e.g. 'y' or 'F') */
  181.    }
  182.    /* extra movement for fast monsters */
  183.    if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp,1);
  184.    return(tmp == 2);
  185. }
  186.  
  187. inrange(mtmp)
  188. register struct monst *mtmp;
  189. {
  190.    register schar tx,ty;
  191.  
  192.    /* spit fire only when both in a room or both in a corridor */
  193.    if(inroom(u.ux,u.uy) != inroom(mtmp->mx,mtmp->my)) return;
  194.    tx = u.ux - mtmp->mx;
  195.    ty = u.uy - mtmp->my;
  196.    if((!tx && abs(ty) < 8) || (!ty && abs(tx) < 8)
  197.        || (abs(tx) == abs(ty) && abs(tx) < 8)){
  198.       /* spit fire in the direction of @ (not nec. hitting) */
  199.       buzz(-1,mtmp->mx,mtmp->my,sgn(tx),sgn(ty));
  200.       if(u.uhp < 1) done_in_by(mtmp);
  201.    }
  202. }
  203.  
  204. m_move(mtmp,after)
  205. register struct monst *mtmp;
  206. {
  207.    register struct monst *mtmp2;
  208.    register int nx,ny,omx,omy,appr,nearer,cnt,i,j;
  209.    xchar gx,gy,nix,niy,chcnt;
  210.    schar chi;
  211.    boolean likegold, likegems, likeobjs;
  212.    schar mmoved = 0;   /* not strictly nec.: chi >= 0 will do */
  213.    coord poss[9];
  214.    int info[9];
  215.  
  216.    if(mtmp->mtrapped) {
  217.       i = mintrap(mtmp);
  218.       if(i == 2) return(2);   /* he died */
  219.       if(i == 1) return(0);   /* still in trap, so didnt move */
  220.    }
  221.    if(mtmp->mhide && o_at(mtmp->mx,mtmp->my) && rn2(10))
  222.       return(0);      /* do not leave hiding place */
  223.  
  224.    /* my dog gets a special treatment */
  225.    if(mtmp->mtame) {
  226.       return( dog_move(mtmp, after) );
  227.    }
  228.  
  229.    /* likewise for shopkeeper */
  230.    if(mtmp->isshk) {
  231.       mmoved = shk_move();
  232.       goto postmov;
  233.    }
  234.  
  235.    /* and for the guard */
  236.    if(mtmp->isgd) {
  237.       mmoved = gd_move();
  238.       goto postmov;
  239.    }
  240.  
  241.    if(mtmp->data->mlet == 't' && !rn2(5)) {
  242.       if(rn2(2))
  243.          mnexto(mtmp);
  244.       else
  245.          rloc(mtmp);
  246.       mmoved = 1;
  247.       goto postmov;
  248.    }
  249.    if(mtmp->data->mlet == 'D' && !mtmp->mcan)
  250.       inrange(mtmp);
  251.    if(!Blind && !Confusion && mtmp->data->mlet == 'U' && !mtmp->mcan
  252.       && cansee(mtmp->mx,mtmp->my) && rn2(5)) {
  253.       pline("%s's gaze has confused you!", Monnam(mtmp));
  254.       if(rn2(5)) mtmp->mcan = 1;
  255.       Confusion = d(3,4);      /* timeout */
  256.    }
  257.    if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
  258.    appr = 1;
  259.    if(mtmp->mflee) appr = -1;
  260.    if(mtmp->mconf || Invis ||  !mtmp->mcansee ||
  261.       (index("BIy",mtmp->data->mlet) && !rn2(3)))
  262.       appr = 0;
  263.    omx = mtmp->mx;
  264.    omy = mtmp->my;
  265.    gx = u.ux;
  266.    gy = u.uy;
  267.    if(mtmp->data->mlet == 'L' && appr == 1 && mtmp->mgold > u.ugold)
  268.       appr = -1;
  269. #ifdef TRACK
  270.    /* random criterion for 'smell'
  271.       should use mtmp->msmell
  272.     */
  273.    if('a' <= mtmp->data->mlet && mtmp->data->mlet <= 'z') {
  274.    extern coord *gettrack();
  275.    register coord *cp;
  276.    schar mroom;
  277.       mroom = inroom(omx,omy);
  278.       if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
  279.           cp = gettrack(omx,omy);
  280.           if(cp){
  281.          gx = cp->x;
  282.          gy = cp->y;
  283.           }
  284.       }
  285.    }
  286. #endif TRACK
  287.    /* look for gold or jewels nearby */
  288.    likegold = (index("LOD", mtmp->data->mlet) != NULL);
  289.    likegems = (index("ODu", mtmp->data->mlet) != NULL);
  290.    likeobjs = mtmp->mhide;
  291. #define   SRCHRADIUS   25
  292.    { xchar mind = SRCHRADIUS;      /* not too far away */
  293.      register int dd;
  294.      if(likegold){
  295.       register struct gen *gold;
  296.       for(gold = fgold; gold; gold = gold->ngen)
  297.         if((dd = DIST(omx,omy,gold->gx,gold->gy)) < mind){
  298.           mind = dd;
  299.           gx = gold->gx;
  300.           gy = gold->gy;
  301.       }
  302.      }
  303.      if(likegems || likeobjs){
  304.       register struct obj *otmp;
  305.       for(otmp = fobj; otmp; otmp = otmp->nobj)
  306.       if(likeobjs || otmp->olet == GEM_SYM)
  307.       if(mtmp->data->mlet != 'u' ||
  308.          objects[otmp->otyp].g_val != 0)
  309.       if((dd = DIST(omx,omy,otmp->ox,otmp->oy)) < mind){
  310.           mind = dd;
  311.           gx = otmp->ox;
  312.           gy = otmp->oy;
  313.       }
  314.      }
  315.      if(mind < SRCHRADIUS && appr == -1) {
  316.       if(dist(omx,omy) < 10) {
  317.           gx = u.ux;
  318.           gy = u.uy;
  319.       } else
  320.           appr = 1;
  321.      }
  322.    }
  323.    nix = omx;
  324.    niy = omy;
  325.    cnt = mfndpos(mtmp,poss,info,
  326.       mtmp->data->mlet == 'u' ? NOTONL :
  327.       index(" VWZ", mtmp->data->mlet) ? NOGARLIC : ALLOW_TRAPS);
  328.       /* ALLOW_ROCK for some monsters ? */
  329.    chcnt = 0;
  330.    chi = -1;
  331.    for(i=0; i<cnt; i++) {
  332.       nx = poss[i].x;
  333.       ny = poss[i].y;
  334.       for(j=0; j<MTSZ && j<cnt-1; j++)
  335.          if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
  336.             if(rn2(4*(cnt-j))) goto nxti;
  337. #ifdef STUPID
  338.       /* some stupid compilers think that this is too complicated */
  339.       { int d1 = DIST(nx,ny,gx,gy);
  340.         int d2 = DIST(nix,niy,gx,gy);
  341.         nearer = (d1 < d2);
  342.       }
  343. #else
  344.       nearer = (DIST(nx,ny,gx,gy) < DIST(nix,niy,gx,gy));
  345. #endif STUPID
  346.       if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
  347.          !mmoved ||
  348.          (!appr && !rn2(++chcnt))){
  349.          nix = nx;
  350.          niy = ny;
  351.          chi = i;
  352.          mmoved = 1;
  353.       }
  354.    nxti:   ;
  355.    }
  356.    if(mmoved){
  357.       if(info[chi] & ALLOW_M){
  358.          mtmp2 = m_at(nix,niy);
  359.          if(hitmm(mtmp,mtmp2) == 1 && rn2(4) &&
  360.            hitmm(mtmp2,mtmp) == 2) return(2);
  361.          return(0);
  362.       }
  363.       if(info[chi] & ALLOW_U){
  364.         (void) hitu(mtmp, d(mtmp->data->damn, mtmp->data->damd)+1);
  365.         return(0);
  366.       }
  367.       mtmp->mx = nix;
  368.       mtmp->my = niy;
  369.       for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
  370.       mtmp->mtrack[0].x = omx;
  371.       mtmp->mtrack[0].y = omy;
  372. #ifndef NOWORM
  373.       if(mtmp->wormno) worm_move(mtmp);
  374. #endif NOWORM
  375.    } else {
  376.       if(mtmp->data->mlet == 'u' && rn2(2)){
  377.          rloc(mtmp);
  378.          return(0);
  379.       }
  380. #ifndef NOWORM
  381.       if(mtmp->wormno) worm_nomove(mtmp);
  382. #endif NOWORM
  383.    }
  384. postmov:
  385.    if(mmoved == 1) {
  386.       if(mintrap(mtmp) == 2)   /* he died */
  387.          return(2);
  388.       if(likegold) mpickgold(mtmp);
  389.       if(likegems) mpickgems(mtmp);
  390.       if(mtmp->mhide) mtmp->mundetected = 1;
  391.    }
  392.    pmon(mtmp);
  393.    return(mmoved);
  394. }
  395.  
  396. mpickgold(mtmp) register struct monst *mtmp; {
  397. register struct gen *gold;
  398.    while(gold = g_at(mtmp->mx, mtmp->my, fgold)){
  399.       mtmp->mgold += gold->gflag;
  400.       freegold(gold);
  401.       if(levl[mtmp->mx][mtmp->my].scrsym == '$')
  402.          newsym(mtmp->mx, mtmp->my);
  403.    }
  404. }
  405.  
  406. mpickgems(mtmp) register struct monst *mtmp; {
  407. register struct obj *otmp;
  408.    for(otmp = fobj; otmp; otmp = otmp->nobj)
  409.    if(otmp->olet == GEM_SYM)
  410.    if(otmp->ox == mtmp->mx && otmp->oy == mtmp->my)
  411.    if(mtmp->data->mlet != 'u' || objects[otmp->otyp].g_val != 0){
  412.       freeobj(otmp);
  413.       mpickobj(mtmp, otmp);
  414.       if(levl[mtmp->mx][mtmp->my].scrsym == GEM_SYM)
  415.          newsym(mtmp->mx, mtmp->my);   /* %% */
  416.       return;   /* pick only one object */
  417.    }
  418. }
  419.  
  420. /* return number of acceptable neighbour positions */
  421. mfndpos(mon,poss,info,flag)
  422. register struct monst *mon; coord poss[9]; int info[9], flag; {
  423. register int x,y,nx,ny,cnt = 0,tmp;
  424. register struct monst *mtmp;
  425.    x = mon->mx;
  426.    y = mon->my;
  427.    if(mon->mconf) {
  428.       flag |= ALLOW_ALL;
  429.       flag &= ~NOTONL;
  430.    }
  431.    for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++)
  432.    if(nx != x || ny != y) if(isok(nx,ny))
  433.    if((tmp = levl[nx][ny].typ) >= DOOR)
  434.    if(!(nx != x && ny != y &&
  435.       (levl[x][y].typ == DOOR || tmp == DOOR))){
  436.       info[cnt] = 0;
  437.       if(nx == u.ux && ny == u.uy){
  438.          if(!(flag & ALLOW_U)) continue;
  439.          info[cnt] = ALLOW_U;
  440.       } else if(mtmp = m_at(nx,ny)){
  441.          if(!(flag & ALLOW_M)) continue;
  442.          info[cnt] = ALLOW_M;
  443.          if(mtmp->mtame){
  444.             if(!(flag & ALLOW_TM)) continue;
  445.             info[cnt] |= ALLOW_TM;
  446.          }
  447.       }
  448.       if(sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
  449.          if(flag & NOGARLIC) continue;
  450.          info[cnt] |= NOGARLIC;
  451.       }
  452.       if(sobj_at(SCR_SCARE_MONSTER, nx, ny) ||
  453.          (!mon->mpeaceful && sengr_at("Elbereth", nx, ny))) {
  454.          if(!(flag & ALLOW_SSM)) continue;
  455.          info[cnt] |= ALLOW_SSM;
  456.       }
  457.       if(sobj_at(ENORMOUS_ROCK, nx, ny)) {
  458.          if(!(flag & ALLOW_ROCK)) continue;
  459.          info[cnt] |= ALLOW_ROCK;
  460.       }
  461.       if(!Invis && online(nx,ny)){
  462.          if(flag & NOTONL) continue;
  463.          info[cnt] |= NOTONL;
  464.       }
  465.             /* we cannot avoid traps of an unknown kind */
  466.             { register struct gen *gtmp = g_at(nx, ny, ftrap);
  467.             register int tt;
  468.             if(gtmp) {
  469.                 tt = 1 << (gtmp->gflag & TRAPTYPE);
  470.                 if(mon->mtrapseen & tt){
  471.                     if(!(flag & tt)) continue;
  472.                     info[cnt] |= tt;
  473.                 }
  474.          }
  475.       }
  476.       poss[cnt].x = nx;
  477.       poss[cnt].y = ny;
  478.       cnt++;
  479.    }
  480.    return(cnt);
  481. }
  482.  
  483. dist(x,y) int x,y; {
  484.    return((x-u.ux)*(x-u.ux) + (y-u.uy)*(y-u.uy));
  485. }
  486.  
  487. poisoned(string, pname)
  488. register char *string, *pname;
  489. {
  490.    if(Blind) pline("It was poisoned.");
  491.    else pline("The %s was poisoned!",string);
  492.    if(Poison_resistance) {
  493.       pline("The poison doesn't seem to affect you.");
  494.       return;
  495.    }
  496.    switch(rnd(6)) {
  497.    case 1:
  498.       u.uhp = -1;
  499.       break;
  500.    case 2:
  501.    case 3:
  502.    case 4:
  503.       losestr(rn1(3,3));
  504.       break;
  505.    case 5:
  506.    case 6:
  507.       losehp(rn1(10,6), pname);
  508.       return;
  509.    }
  510.    if(u.uhp < 1) killer = pname;
  511. }
  512.  
  513. mondead(mtmp)
  514. register struct monst *mtmp;
  515. {
  516.     relobj(mtmp,1);
  517.     unpmon(mtmp);
  518.     relmon(mtmp);
  519.     if(u.ustuck == mtmp) {
  520.         u.ustuck = 0;
  521.         if(u.uswallow) {
  522.             u.uswldtim = 0;
  523.             u.uswallow = 0;
  524.             setsee();
  525.             docrt();
  526.       }
  527.    }
  528.    if(mtmp->isshk) shkdead();
  529.    if(mtmp->isgd) gddead();
  530. #ifndef NOWORM
  531.    if(mtmp->wormno) wormdead(mtmp);
  532. #endif NOWORM
  533.    monfree(mtmp);
  534. }
  535.  
  536. /* called when monster is moved to larger structure */
  537. replmon(mtmp,mtmp2)
  538. register struct monst *mtmp, *mtmp2;
  539. {
  540.    relmon(mtmp);
  541.    monfree(mtmp);
  542.    mtmp2->nmon = fmon;
  543.    fmon = mtmp2;
  544. }
  545.  
  546. relmon(mon)
  547. register struct monst *mon;
  548. {
  549.    register struct monst *mtmp;
  550.  
  551.    if(mon == fmon) fmon = fmon->nmon;
  552.    else {
  553.       for(mtmp = fmon; mtmp->nmon != mon; mtmp = mtmp->nmon) ;
  554.       mtmp->nmon = mon->nmon;
  555.    }
  556. }
  557.  
  558. /* we do not free monsters immediately, in order to have their name
  559.    available shortly after their demise */
  560. struct monst *fdmon;   /* chain of dead monsters, need not to be saved */
  561.  
  562. monfree(mtmp) register struct monst *mtmp; {
  563.    mtmp->nmon = fdmon;
  564.    fdmon = mtmp;
  565. }
  566.  
  567. dmonsfree(){
  568. register struct monst *mtmp;
  569.    while(mtmp = fdmon){
  570.       fdmon = mtmp->nmon;
  571.       free((char *) mtmp);
  572.    }
  573. }
  574.  
  575. killed(mtmp) struct monst *mtmp; {
  576. #ifdef lint
  577. #define   NEW_SCORING
  578. #endif lint
  579. register int tmp,tmp2,nk,x,y;
  580. register struct permonst *mdat = mtmp->data;
  581.    if(mtmp->cham) mdat = PM_CHAM;
  582.    if(Blind) pline("You destroy it!");
  583.    else {
  584.       pline("You destroy %s!",
  585.          mtmp->mtame ? amonnam(mtmp, "poor") : monnam(mtmp));
  586.    }
  587.    if(u.umconf) {
  588.       if(!Blind) pline("Your hands stop glowing blue.");
  589.       u.umconf = 0;
  590.    }
  591.  
  592.    /* count killed monsters */
  593. #define   MAXMONNO   100
  594.    nk = 1;            /* in case we cannot find it in mons */
  595.    tmp = mdat - mons;    /* index in mons array (if not 'd', '@', ...) */
  596.    if(tmp >= 0 && tmp < CMNUM+2) {
  597.        extern char fut_geno[];
  598.        u.nr_killed[tmp]++;
  599.        if((nk = u.nr_killed[tmp]) > MAXMONNO &&
  600.       !index(fut_geno, mdat->mlet))
  601.           charcat(fut_geno,  mdat->mlet);
  602.    }
  603.  
  604.    /* punish bad behaviour */
  605.    if(mdat->mlet == '@') Telepat = 0, u.uluck -= 2;
  606.    if(mtmp->mpeaceful || mtmp->mtame) u.uluck--;
  607.    if(mdat->mlet == 'u') u.uluck -= 5;
  608.  
  609.    /* give experience points */
  610.    tmp = 1 + mdat->mlevel * mdat->mlevel;
  611.    if(mdat->ac < 3) tmp += 2*(7 - mdat->ac);
  612.    if(index("AcsSDXaeRTVWU&In:P", mdat->mlet))
  613.       tmp += 2*mdat->mlevel;
  614.    if(index("DeV&P",mdat->mlet)) tmp += (7*mdat->mlevel);
  615.    if(mdat->mlevel > 6) tmp += 50;
  616.  
  617. #ifdef NEW_SCORING
  618.    /* ------- recent addition: make nr of points decrease
  619.          when this is not the first of this kind */
  620.    { int ul = u.ulevel;
  621.      int ml = mdat->mlevel;
  622.  
  623.    if(ul < 14)    /* points are given based on present and future level */
  624.        for(tmp2 = 0; !tmp2 || ul + tmp2 <= ml; tmp2++)
  625.       if(u.uexp + 1 + (tmp + ((tmp2 <= 0) ? 0 : 4<<(tmp2-1)))/nk
  626.           >= 10*pow((unsigned)(ul-1)))
  627.          if(++ul == 14) break;
  628.  
  629.    tmp2 = ml - ul -1;
  630.    tmp = (tmp + ((tmp2 < 0) ? 0 : 4<<tmp2))/nk;
  631.    if(!tmp) tmp = 1;
  632.    }
  633.    /* note: ul is not necessarily the future value of u.ulevel */
  634.    /* ------- end of recent valuation change ------- */
  635. #endif NEW_SCORING
  636.  
  637.    u.uexp += tmp;
  638.    u.urexp += 4*tmp;
  639.    flags.botl = 1;
  640.    while(u.ulevel < 14 && u.uexp >= 10*pow(u.ulevel-1)){
  641.       pline("Welcome to level %d.", ++u.ulevel);
  642.       tmp = rnd(10);
  643.       if(tmp < 3) tmp = rnd(10);
  644.       u.uhpmax += tmp;
  645.       u.uhp += tmp;
  646.       flags.botl = 1;
  647.    }
  648.  
  649.    /* dispose of monster and make cadaver */
  650.    x = mtmp->mx;   y = mtmp->my;
  651.    mondead(mtmp);
  652.    tmp = mdat->mlet;
  653.    if(tmp == 'm') { /* he killed a minotaur, give him a wand of digging */
  654.          /* note: the dead minotaur will be on top of it! */
  655.       mksobj_at(WAND_SYM, WAN_DIGGING, x, y);
  656.       /* if(cansee(x,y)) atl(x,y,fobj->olet); */
  657.       stackobj(fobj);
  658.    } else
  659. #ifndef NOWORM
  660.    if(tmp == 'w') {
  661.       mksobj_at(WEAPON_SYM, WORM_TOOTH, x, y);
  662.       stackobj(fobj);
  663.    } else
  664. #endif   NOWORM
  665.    if(!letter(tmp) || !rn2(3)) tmp = 0;
  666.  
  667.    if(levl[x][y].typ >= DOOR)   /* might be mimic in wall */
  668.        if(x != u.ux || y != u.uy) /* might be here after swallowed */
  669.       if(index("NTVm&",mdat->mlet) || rn2(5)) {
  670.       mkobj_at(tmp,x,y);
  671.       if(cansee(x,y)) atl(x,y,fobj->olet);
  672.       stackobj(fobj);
  673.    }
  674. }
  675.  
  676. kludge(str,arg)
  677. register char *str,*arg;
  678. {
  679.    if(Blind) {
  680.       if(*str == '%') pline(str,"It");
  681.       else pline(str,"it");
  682.    } else pline(str,arg);
  683. }
  684.  
  685. rescham()   /* force all chameleons to become normal */
  686. {
  687.    register struct monst *mtmp;
  688.  
  689.    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
  690.       if(mtmp->cham) {
  691.          mtmp->cham = 0;
  692.          (void) newcham(mtmp,PM_CHAM);
  693.       }
  694. }
  695.  
  696. newcham(mtmp,mdat)   /* make a chameleon look like a new monster */
  697.          /* returns 1 if the monster actually changed */
  698. register struct monst *mtmp;
  699. register struct permonst *mdat;
  700. {
  701.    register int mhp, hpn, hpd;
  702.  
  703.    if(mdat == mtmp->data) return(0);   /* still the same monster */
  704. #ifndef NOWORM
  705.    if(mtmp->wormno) wormdead(mtmp);   /* throw tail away */
  706. #endif NOWORM
  707.    hpn = mtmp->mhp;
  708.    hpd = (mtmp->data->mlevel)*8;
  709.    if(!hpd) hpd = 4;
  710.    mtmp->data = mdat;
  711.    mhp = (mdat->mlevel)*8;
  712.    /* new hp: same fraction of max as before */
  713.    mtmp->mhp = 2 + (hpn*mhp)/hpd;
  714.    hpn = mtmp->orig_hp;
  715.    mtmp->orig_hp = 2 + (hpn*mhp)/hpd;
  716.    mtmp->minvis = (mdat->mlet == 'I') ? 1 : 0;
  717. #ifndef NOWORM
  718.    if(mdat->mlet == 'w' && getwn(mtmp)) initworm(mtmp);
  719. #endif NOWORM
  720.    unpmon(mtmp);   /* necessary for 'I' and to force pmon */
  721.             /* perhaps we should clear mtmp->mtame here? */
  722.    pmon(mtmp);
  723.    return(1);
  724. }
  725.  
  726. mnexto(mtmp)   /* Make monster mtmp next to you (if possible) */
  727. struct monst *mtmp;
  728. {
  729.    extern coord enexto();
  730.    coord mm;
  731.    mm = enexto(u.ux, u.uy);
  732.    mtmp->mx = mm.x;
  733.    mtmp->my = mm.y;
  734.    pmon(mtmp);
  735. }
  736.  
  737. rloc(mtmp)
  738. struct monst *mtmp;
  739. {
  740.    register int tx,ty;
  741.    register char ch = mtmp->data->mlet;
  742.  
  743. #ifndef NOWORM
  744.    if(ch == 'w' && mtmp->mx) return;   /* do not relocate worms */
  745. #endif NOWORM
  746.    do {
  747.       tx = rn1(COLNO-3,2);
  748.       ty = rn2(ROWNO);
  749.    } while(!goodpos(tx,ty));
  750.    mtmp->mx = tx;
  751.    mtmp->my = ty;
  752.    if(u.ustuck == mtmp){
  753.       if(u.uswallow) {
  754.          u.ux = tx;
  755.          u.uy = ty;
  756.          docrt();
  757.       } else   u.ustuck = 0;
  758.    }
  759.    pmon(mtmp);
  760. }
  761.  
  762. ishuman(mtmp) register struct monst *mtmp; {
  763.    return(mtmp->data->mlet == '@');
  764. }
  765.  
  766. setmangry(mtmp) register struct monst *mtmp; {
  767.    if(!mtmp->mpeaceful) return;
  768.    if(mtmp->mtame) return;
  769.    mtmp->mpeaceful = 0;
  770.    if(ishuman(mtmp)) pline("%s gets angry!", Monnam(mtmp));
  771. }
  772.